﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using Daybreak.Core;
using Daybreak.Core.Rendering;
using Daybreak.Core.SceneGraph;

namespace Tutorial1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Demo : Tutorials.TutorialApp
    {
        public Demo()
        {
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();

        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            base.LoadContent();

            scene.SceneInstance.CreateDefaultLighting();

            Switch rootSwitcher = new Switch();
            rootSwitcher.Expression += new Switch.Method(rootSwitcher_Expression);

            scene.SceneInstance.AddRootNode(rootSwitcher);

            CreateScene(rootSwitcher, scene); // scene 1 

            scene.Images.Load(false);

            xnaEngine.ShowScene(scene);

            xnaEngine.Camera = new MouseCamera(1);
            xnaEngine.Camera.Position = new Vector3(20, 10, 20);
            xnaEngine.Camera.RotationDegrees = new Vector2(10, 230);


        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void DrawFrame(GameTime gameTime)
        {
            int time = (int)gameTime.ElapsedRealTime.TotalMilliseconds;
            WriteText("FPS " + fpsCounter.Fps.ToString(), 10, 10, Color.Yellow);
            WriteText("FrameTime (ms) x 60 = " + time * 60, 10, 25, Color.Yellow);

        }


        private void CreateScene(Group rootNode, Scene scene)
        {
            Scene.Image img1 = scene.CreateImage("texture1", "clouds.jpg");

            Scene.Material mat1 = scene.CreateMaterial("default1", img1);
            Scene.Material mat2 = Scene.Material.Debug;

            // create textured box geometry
            Geometry boxGeom = scene.CreateGeometry("Box01-mesh");
            Geometry.Factory.CreateBoxMesh(1, 1, 1, boxGeom, mat1);

            Geometry sphereGeom = scene.CreateGeometry("Sphere01-mesh");
            Geometry.Factory.CreateSphereMesh(1.5f, 15, 17, sphereGeom, mat1);

            Transform.Matrix44 transformNode1 = new Transform.Matrix44();
            transformNode1.Move(0, 1, 0, false);

            Geode boxNode = new Geode();

            boxNode.AddDrawables(boxGeom.CreateInstance(scene));
            //boxNode.AddDrawables(sphereGeom.CreateInstance(scene));

            Transform.Matrix44 transformNode2 = new Transform.Matrix44();
            transformNode2.Move(3, 0, 0, false);

            Transform.Matrix44 transformNode3 = new Transform.Matrix44();
            transformNode3.Move(-3, 0, 0, false);

            // adding the same box node three times
            transformNode1.AddChild(boxNode); // root
            transformNode2.AddChild(boxNode);
            transformNode3.AddChild(boxNode);

            // create hierarchy
            transformNode1.AddChild(transformNode2);
            transformNode1.AddChild(transformNode3);

            transformNode1.OnUpdate += new Node.UpdateHandler(transformNode1_OnUpdate);
            transformNode2.OnUpdate += new Node.UpdateHandler(transformNode2_OnUpdate);
            transformNode3.OnUpdate += new Node.UpdateHandler(transformNode3_OnUpdate);

            rootNode.AddChild(transformNode1);

        }

        void rootSwitcher_Expression(Switch node, float deltaTime)
        {
            node.ActiveNodeIndex = 0;
        }
        
        void transformNode1_OnUpdate(Node node, NodeVisitor updater, float deltaTime)
        {
            Transform.Matrix44 transformer = node as Transform.Matrix44;

            if (transformer == null)
                return;

            transformer.RotateY(-1f, true);
        }

        void transformNode2_OnUpdate(Node node, NodeVisitor updater, float deltaTime)
        {
            Transform.Matrix44 transformer = node as Transform.Matrix44;

            if (transformer == null)
                return;

            transformer.RotateX(2, true);
        }

        void transformNode3_OnUpdate(Node node, NodeVisitor updater, float deltaTime)
        {
            Transform.Matrix44 transformer = node as Transform.Matrix44;

            if (transformer == null)
                return;

            transformer.RotateX(-2, true);
        }

    }
}
